<template>
  <fks-row class="flow-button-warp">
    <slot name="before" />
    <template v-if="type !== 'view'">
      <fks-button
        v-for="(item, index) in buttonList"
        :key="index"
        :plain="item.type !== 'submit'"
        :type="buttonType(item)"
        :loading="loading"
        @click="clickHandler(item)"
      >
        <i
          v-if="!loading"
          style="margin-right: 6px; vertical-align: middle"
          :class="`fks-icon-${buttonIcon(item)}`"
        />
        <span style="display: inline-block; vertical-align: middle">{{
          LANG[item.customCode || item.code] || item.text
        }}</span>
      </fks-button>
    </template>
    <template v-if="type === 'view'">
      <fks-button
        type="primary"
        :loading="loading"
        @click="getPdf"
      >
        打印表单
      </fks-button>
    </template>
    <slot name="after" />
    <fks-dialog
      title="选择加签人"
      append-to-body
      :visible.sync="addCounterInfo.visible"
      width="400px"
    >
      <fks-form>
        <fks-form-item label="选择委托人">
          <fks-user-selector
            style="width: 100%;"
            url
            multiple
            :username.sync="addCounterInfo.userName"
            :userfullname.sync="addCounterInfo.userFullName"
          />
        </fks-form-item>
      </fks-form>
      <span
        slot="footer"
        class="dialog-footer"
      >
        <fks-button @click="addCounterInfo.visible = false">取 消</fks-button>
        <fks-button
          type="primary"
          @click="addCounterHandler"
        >确 定</fks-button>
      </span>
    </fks-dialog>
    <fks-dialog
      title="选择抄送人"
      append-to-body
      :visible.sync="circulationInfo.visible"
      width="400px"
      @open="open"
      @close="cancel()"
    >
      <fks-form>
        <fks-form-item label="抄送人">
          <fks-user-selector
            style="width: 100%;"
            url
            multiple
            :username.sync="circulationInfo.userName"
            :userfullname.sync="circulationInfo.userFullName"
          />
        </fks-form-item>
        <fks-form-item label="抄送人通知方式">
          <fks-checkbox-group
            v-model="notifyMethods"
            @change="handleNotifyMethodsChange"
          >
            <fks-checkbox
              v-for="item in notifyMethodOptions"
              :key="item.value"
              :label="item.value"
            >
              {{ item.label }}
            </fks-checkbox>
          </fks-checkbox-group>
        </fks-form-item>
      </fks-form>
      <span
        slot="footer"
        class="dialog-footer"
      >
        <fks-button @click="cancel">取 消</fks-button>
        <fks-button
          type="primary"
          @click="circulationInfoHandler"
        >确 定</fks-button>
      </span>
    </fks-dialog>
    <fks-dialog
      title="选择退回节点"
      :visible.sync="innerRejectVisible"
      append-to-body
      @close="cancelReject()"
    >
      <fks-select
        v-model="rejectNode"
        placeholder="请选择退回节点"
      >
        <fks-option
          v-for="item in rejectNodeOptions"
          :key="item.taskKey"
          :label="item.taskName"
          :value="item.taskKey"
        />
      </fks-select>
      <div
        slot="footer"
        class="dialog-footer"
      >
        <fks-button @click="cancelReject()">
          取 消
        </fks-button>
        <fks-button
          type="primary"
          @click="confirmReject()"
        >
          确 定
        </fks-button>
      </div>
    </fks-dialog>
  </fks-row>
</template>
<script>
import Mix from '@/mixins/module'
import downloadPdf from '@/utils/htmlToPdf'
import {
  processAbandon,
  processStart,
  processComplete,
  processMulti,
  processReject,
  processButton,
  processTaskKey,
  saveCustomNodeDetail,
  circulation,
  getCustomNodeDetail
} from './api'
export default {
  name: 'FormButton',
  mixins: [Mix],
  inject: ['parentComponent'],
  props: {
    taskId: {
      type: String,
      default: ''
    },
    taskKey: {
      type: String,
      default: ''
    },
    processInstanceId: {
      type: String,
      default: ''
    },
    comment: {
      type: String,
      default: ''
    },
    approval: {
      type: String,
      default: ''
    },
    targetKey: {
      type: String,
      default: ''
    },
    processDefinitionId: {
      type: String,
      default: ''
    },
    isCustom: {
      type: Boolean,
      default: () => {
        return false
      }
    },
    customAssigneeGroup: {
      type: Object,
      default: () => {
        return {}
      }
    },
    customAssigneeList: {
      type: Array,
      default: () => {
        return []
      }
    },
    type: {
      type: String,
      default: ''
    },
    userNameList: {
      type: Array,
      default: () => {
        return []
      }
    },
    formKey: {
      type: String,
      default: ''
    },
    formName: {
      type: String,
      default: ''
    },
    modelKey: {
      type: String,
      default: ''
    },
    bizId: {
      type: String,
      default: ''
    },
    stageFlag: {
      type: Number,
      default: 0
    },
    variable: {
      type: Object,
      default: () => {
        return {}
      }
    },
    beforeSubmit: {
      // 提交前钩子
      type: Function,
      default: () => {}
    },
    afterSubmit: {
      // 提交后钩子
      type: Function,
      default: () => {}
    },
    // onOptSuccess: {
    //   // 点击任意按钮以后的处理方法
    //   type: Function,
    //   default: () => {}
    // },
    beforeDraft: {
      // 点击暂存的处理方法
      type: Function,
      default: () => {}
    }
  },
  data() {
    return {
      flowData: {
        modelKey: this.modelKey,
        bizId: this.bizId,
        processInstanceId: this.processInstanceId,
        formKey: this.formKey,
        stageFlag: this.stageFlag,
        variable: JSON.stringify(this.variable),
        taskId: this.taskId,
        approval: this.approval,
        comment: this.comment,
        targetKey: ''
      },
      circulationInfo: {
        visible: false, // 选择退回节点对话框
        userName: '',
        userFullName: '',
        notify: ''
      },
      notifyMethods: [],
      notifyMethodOptions: [
        {
          label: '站内信',
          value: '0'
        },
        {
          label: '短信',
          value: '1'
        },
        {
          label: '邮件',
          value: '2'
        }
      ],
      addCounterInfo: {
        visible: false, // 选择退回节点对话框
        userName: '',
        userFullName: '',
        targetNode: ''
        // flowIndex: '',
        // flowDetail: []
      },
      buttonList: [],
      loading: false,
      innerRejectVisible: false,
      rejectNodeOptions: [],
      rejectNode: ''
    }
  },
  watch: {
    modelKey(val) {
      this.flowData.modelKey = val
    }
  },
  mounted() {
    if (this.taskId && this.type === 'execute') {
      this.getButton()
    } else if (this.type && this.type === 'add') {
      this.buttonList = [
        {
          type: 'saveDraft',
          text: '暂存',
          code: 'SAVEDRAFT',
          customCode: 'SAVEDRAFT'
        },
        {
          type: 'submit',
          text: '提交',
          code: 'SUBMIT',
          customCode: 'SUBMIT'
        }
      ]
    } else if (this.type && this.type === 'edit') {
      this.buttonList = [
        {
          type: 'submit',
          text: '修改',
          code: 'EDIT',
          customCode: 'SUBMIT'
        }
      ]
    }
  },
  methods: {
    //打印PDF
    getPdf() {
      this.loading = true
      let dom = this.parentComponent.$refs.dialog.$el.getElementsByClassName(
        'fks-dialog__body'
      )[0]
      let title = this.formName
      downloadPdf(dom, title).then(() => {
        this.loading = false
      })
    },
    handleNotifyMethodsChange(val) {
      if (val && val.length && val.length > 0) {
        this.circulationInfo.notify = val.join()
      } else {
        this.circulationInfo.notify = ''
      }
    },
    buttonType(item) {
      switch (item.type) {
        case 'submit':
          return 'primary'
        default:
          return ''
      }
    },
    buttonIcon(item) {
      switch (item.type) {
        case 'abandon':
          return 'delete'
        case 'reject':
          return 'reject'
        case 'submit':
          return 'check'
        case 'saveDraft':
          return 'hold'
        case 'addCountersignee':
          return 'circle-plus-outline'
        case 'edit':
          return 'edit'
          // 图标缺失
        case 'circulate':
          return 'circulate'
        default:
          return ''
      }
    },
    sortIcon(item) {
      switch (item.type) {
        case 'submit':
          return 1
        case 'saveDraft':
          return 2
        case 'reject':
          return 3
        case 'abandon':
          return 4
        case 'addCountersignee':
          return 5
        case 'edit':
          return 6
        case 'circulate':
          return 7
        default:
          return 8
      }
    },
    confirmReject() {
      let rejectIndex = this.buttonList.findIndex(
        (item) => item.type == 'reject'
      )
      if (rejectIndex > -1) {
        let buttonInfo = this.buttonList[rejectIndex]
        buttonInfo.targetNode = this.rejectNode
        this.reject(buttonInfo)
      }
      this.loading = false
    },
    cancelReject() {
      this.loading = false
      this.rejectNode = ''
      this.rejectNodeOptions = []
      this.innerRejectVisible = false
    },
    /**
     * @description: 按钮点击事件
     * @param {type} 按钮触发的方法类型
     */
    clickHandler(buttonInfo) {
      this.loading = true
      if (buttonInfo.type == 'reject' && !this.isCustom) {
        //只有一个退回节点直接退回并return
        if (buttonInfo.targetNode.length === 1) {
          buttonInfo.targetNode = buttonInfo.targetNode[0]
          this.reject(buttonInfo)
          return
        }
        processTaskKey(this.processTaskKey, this.taskId).then((res) => {
          if (res.status) {
            let nodeArr = res.data
            let rejectNodeArr =
              Object.prototype.toString.call(buttonInfo.targetNode) ==
              '[object Array]'
                ? buttonInfo.targetNode
                : JSON.parse(buttonInfo.targetNode)
            for (const item of nodeArr) {
              if (rejectNodeArr.indexOf(item.taskKey) !== -1) {
                this.rejectNodeOptions.push(item)
              }
            }
          }
        })
        this.innerRejectVisible = true
      } else if (buttonInfo.type == 'circulate') {
        this.circulate(buttonInfo)
      } else {
        this.$confirm(
          // this.LANG[buttonInfo.customCode] +
          // this.LANG.CONFIRM_TIPS +
          //   ' ' +
          '确认' +
            (this.LANG[buttonInfo.customCode || buttonInfo.code] ||
              buttonInfo.text) +
            '？',
          this.LANG.TIPS,
          {
            confirmButtonText: this.LANG.CONFIRM,
            cancelButtonText: this.LANG.CANCEL,
            type: 'warning'
          }
        )
          .then(() => {
            this[buttonInfo.type](buttonInfo)
          })
          .catch(() => {
            // 提交确认界面点击取消以后
            this.loading = false
            // this.$message({
            //   type: 'info',
            //   message: this.LANG.CANCEL
            // })
          })
      }
    },
    /**
     * @description: 完成操作成功之后的回调
     */
    // onOptSuccess() {
    //   this.$emit('on-success')
    // },
    getButton() {
      if (this.taskId) {
        processButton(this.taskId).then((res) => {
          const tempButtonList = JSON.parse(res.data.buttonList)
          if (
            tempButtonList.taskButtonList &&
            tempButtonList.taskButtonList.length
          ) {
            this.buttonList = tempButtonList.taskButtonList.sort(
              (a, b) => this.sortIcon(b) - this.sortIcon(a)
            )
          } else {
            this.buttonList = tempButtonList.sort(
              (a, b) => this.sortIcon(b) - this.sortIcon(a)
            )
          }
        })
      }
    },
    buttonCompute(data) {
      // return this.buttonList.indexOf(data) != -1
      return true
    },
    /**
     * @description: 提交请求
     */
    submit() {
      // 点击确认以后进行提交操作
      const before = this.beforeSubmit
      const after = this.afterSubmit
      if (before) {
        // 有传入beforeSubmit方法
        before()
          .then((res) => {
            this.setFlowDataVariable()
            if (this.type === 'edit') {
              this.onOptSuccess({ status: true }, 'MODIFY')
              return
            }
            this.flowData.stageFlag = 0
            this.flowData.comment = this.comment
            this.flowData.formKey = this.formKey
            this.flowData.bizId = this.bizId
            if (this.taskId) {
              // 若有taskId则为执行流程
              processComplete(this.flowData)
                .then((res) => {
                  if (
                    this.isCustom &&
                    res.status &&
                    this.processInstanceId &&
                    this.bizId
                  ) {
                    this.saveCustomFlowDetail(
                      this.processInstanceId,
                      this.bizId
                    )
                  }
                  after && after()
                  this.onOptSuccess(res, 'SUBMIT')
                })
                .catch((err) => {
                  this.catchHandler(err)
                })
            } else {
              // 无taskId则为启动流程
              //流程start时需要加入自由流程标识符，与普通表单区分
              //自由流程表单启动 需要参数customProcessFlag:'1'
              let data = this.isCustom
                ? { ...this.flowData, customProcessFlag: '1' }
                : this.flowData
              processStart(data)
                .then((res) => {
                  if (this.isCustom && res.status && res.data) {
                    this.saveCustomFlowDetail(
                      res.data.processInstanceId,
                      res.data.bizId
                    )
                  }
                  after && after()
                  this.onOptSuccess(res, 'SUBMIT')
                })
                .catch((err) => {
                  this.catchHandler(err)
                })
            }
          })
          .catch((err) => {
            this.catchHandler(err)
          })
      } else {
        if (this.type === 'edit') {
          this.onOptSuccess({ status: true }, 'MODIFY')
          return
        }
        if (this.taskId) {
          processComplete(this.flowData)
            .then((res) => {
              if (
                this.isCustom &&
                res.status &&
                this.processInstanceId &&
                this.bizId
              ) {
                this.saveCustomFlowDetail(this.processInstanceId, this.bizId)
              }
              after && after()
              this.onOptSuccess(res, 'SUBMIT')
            })
            .catch((err) => {
              this.catchHandler(err)
            })
        } else {
          //流程start时需要加入自由流程标识符，与普通表单区分
          //自由流程表单启动 需要参数customProcessFlag:'1'
          let data = this.isCustom
            ? { ...this.flowData, customProcessFlag: '1' }
            : this.flowData
          processStart(data)
            .then((res) => {
              if (this.isCustom && res.status && res.data) {
                this.saveCustomFlowDetail(
                  res.data.processInstanceId,
                  res.data.bizId
                )
              }
              after && after()
              this.onOptSuccess(res, 'SUBMIT')
            })
            .catch((err) => {
              this.catchHandler(err)
            })
        }
      }
    },
    /**
     * @description: 暂存
     */
    saveDraft() {
      const before = this.beforeDraft
      before()
        .then((result) => {
          this.setFlowDataVariable()
          this.flowData.stageFlag = 1
          this.flowData.approval = 'stage' // 暂存审批类型标识
          this.flowData.comment = this.comment || '暂存'
          this.flowData.bizId = this.bizId
          this.flowData.formKey = this.formKey
          if (!this.taskId) {
            // processStart(this.flowData)
            //流程start时需要加入自由流程标识符，与普通表单区分
            //自由流程表单启动 需要参数customProcessFlag:'1'
            let data = this.isCustom
              ? { ...this.flowData, customProcessFlag: '1' }
              : this.flowData
            processStart(data)
              .then((res) => {
                if (this.isCustom && res.status && res.data) {
                  this.saveCustomFlowDetail(
                    res.data.processInstanceId,
                    res.data.bizId
                  )
                }
                this.onOptSuccess(res, 'SAVEDRAFT')
              })
              .catch((err) => {
                this.catchHandler(err)
              })
          } else {
            processComplete(this.flowData)
              .then((res) => {
                if (
                  this.isCustom &&
                  res.status &&
                  this.processInstanceId &&
                  this.bizId
                ) {
                  this.saveCustomFlowDetail(this.processInstanceId, this.bizId)
                }
                this.onOptSuccess(res, 'SAVEDRAFT')
              })
              .catch((err) => {
                this.catchHandler(err)
              })
          }
        })
        .catch((err) => {
          this.catchHandler(err)
        })
    },
    /**
     * @description: 驳回到指定节点
     * @param {taskId} 任务id
     * @param {comment} 评论
     * @param {targetKey} 指定节点
     */
    reject(buttonInfo) {
      this.flowData.taskId = this.taskId
      this.flowData.bizId = this.bizId
      this.flowData.comment = this.comment
      this.flowData.targetKey = buttonInfo.targetNode || buttonInfo.rejectNode
      processReject(this.flowData)
        .then((res) => {
          if (res.status) {
            this.onOptSuccess(res, 'REJECT')
          }
        })
        .catch((err) => {
          this.catchHandler(err)
        })
      this.loading = false
      // this.onOptSuccess(res)
    },
    /**
     * @description: 驳回到上一节点
     * @param {taskId} 任务id
     * @param {comment} 评论
     */
    rejectLastNode() {
      this.flowData.taskId = this.taskId
      this.flowData.bizId = this.bizId
      this.flowData.comment = this.comment
      processReject(this.flowData)
        .then((res) => {
          this.onOptSuccess(res, 'REJECT')
        })
        .catch((err) => {
          this.catchHandler(err)
        })
    },
    /**
     * @description: 废弃
     */
    abandon() {
      this.flowData.taskId = this.taskId
      this.flowData.bizId = this.bizId
      this.flowData.comment = this.comment
      this.flowData.formKey = this.formKey
      processAbandon(this.flowData)
        .then((res) => {
          this.onOptSuccess(res, 'ABANDON')
        })
        .catch((err) => {
          this.catchHandler(err)
        })
    },
    /**
     * @description: 加签
     */
    addCountersignee(buttonInfo) {
      this.addCounterInfo.targetNode = buttonInfo.targetNode
      this.addCounterInfo.visible = true
    },
    open() {
      this.circulationInfo.userName = ''
      this.circulationInfo.userFullName = ''
      this.notifyMethods = []
    },
    cancel() {
      this.circulationInfo.visible = false
      this.loading = false
    },
    /**
     * @description: 抄送
     */
    circulate(buttonInfo) {
      console.log(buttonInfo)
      this.circulationInfo.visible = true
    },
    circulationInfoHandler() {
      if (
        this.circulationInfo.userName &&
        this.circulationInfo.userName.length
      ) {
        circulation({
          formBizId: this.flowData.bizId,
          formKey: this.flowData.formKey,
          processInstanceId: this.flowData.processInstanceId,
          processType: this.isCustom ? 2 : 1,
          receiverUserName: this.circulationInfo.userName,
          receiverUserFullName: this.circulationInfo.userFullName,
          notify: this.circulationInfo.notify,
          senderUserFullName: this.$store.state.user.userFullname,
          senderUserName: this.$store.state.user.userName,
          taskId: this.flowData.taskId,
          title: this.formName || '',
          sourceId: this.$store.state.portal.id || '',
          sourceName: this.$store.state.portal.name || ''
        }).then((res) => {
          this.receiverUserName = ''
          this.$message.success('抄送成功')
          this.circulationInfo.visible = false
          this.loading = false
        })
      } else {
        this.$message.error('无抄送人')
      }
    },
    addCounterHandler() {
      // 选择完加签人后进行流程提交
      if (this.addCounterInfo.targetNode && this.addCounterInfo.userName) {
        processMulti(
          'add',
          this.taskId,
          this.addCounterInfo.targetNode,
          this.addCounterInfo.userName
        ).then((res) => {
          this.addCounterInfo.targetNode = ''
          this.addCounterInfo.userName = ''
          this.addCounterInfo.userFullName = ''
          this.addCounterInfo.visible = false
          this.onOptSuccess(res, 'ADDCOUNTER')
        })
      } else {
        if (this.addCounterInfo.userName) {
          this.addCounterInfo.visible = false
          this.onOptSuccess({
            status: false,
            message: 'No assignee or node'
          })
        } else {
          this.$message.warning('No assignee')
        }
      }
    },
    /**
     * @description: 减签
     */
    deleteCountersignee() {
      processMulti('delete', this.taskId, this.taskKey, this.userNameList).then(
        (res) => {
          this.onOptSuccess(res, 'DELETECONTER')
        }
      )
    },
    /**
     * @description: 展示流程状态
     */
    showFlowState() {
      // console.log('暂未开发')
      // this.onOptSuccess(res)
    },
    /**
     * @description: 打开选择退回节点dialog
     */
    stepClickHandler(stepId) {
      this.flowIndex = this.flowIndex == stepId ? '' : stepId
    },
    onOptSuccess(data, type) {
      if (data.status) {
        this.$emit('onSuccess', data, type)
      } else {
        this.$emit('onError', data, type)
      }
      this.loading = false
    },
    /**
     * @description:
     * @param {type}
     * @return:
     */
    catchHandler(error) {
      console.log(error)
      this.loading = false
      this.$emit('onCatch', error)
    },
    /**
     * @description: 保存自由流程审批人相关参数
     */
    saveCustomFlowDetail(processInstanceId, bizId) {
      if (this.isCustom && processInstanceId && bizId) {
        // 如果自定义流程则保存所有审批节点信息
        this.customAssigneeList.forEach((assignee) => {
          assignee.processInstanceId = processInstanceId
          assignee.bizId = bizId
        })
        saveCustomNodeDetail(this.customAssigneeList).then((res) => {
          if (!res.status){
            console.log('save error: custom-flow')
          }
        })
      }
    },
    setFlowDataVariable() {
      if (this.isCustom) {
        // 如果为自由流程则需要增加自由流程执行参数
        this.flowData.variable = JSON.stringify(
          Object.assign(this.customAssigneeGroup, this.variable)
        )
      } else {
        this.flowData.variable = JSON.stringify(this.variable)
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.flow-button-warp {
  ::v-deep .flow-button-inner {
    display: inline-block;
    align-items: center;
  }

  .fks-steps {
    .fks-step {
      cursor: pointer;
    }

    .fks-step.active {
      .fks-step__main {
        color: #4ccae3 !important;
      }

      .fks-step__title {
        color: #4ccae3 !important;
      }

      .fks-step__description {
        color: #4ccae3 !important;
      }

      .fks-step__icon {
        border-color: #4ccae3 !important;
        color: #4ccae3 !important;
      }
    }
  }
}
</style>
